﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WordRacer.Domain.Model.Dictionaries;
using WordRacer.Domain.Model.Boards;
using WordRacer.Domain.Model.GameCells;

    /// <summary>
    /// + --- + --- + --- + --- +                 + --- + --- + --- + --- +
    /// |  S  |  E  |  M  |  H  |                 |  1  |  2  |  3  |  4  | ordinal reference locations
    /// + --- + --- + --- + --- +                 + --- + --- + --- + --- +
    /// |  A  |  Q  |  W  |  G  |                 |  5  |  6  |  7  |  8  |
    /// + --- + --- + --- + --- +                 + --- + --- + --- + --- +
    /// |  B  |  N  |  E  |  O  |                 |  9  |  10 |  11 |  12 |
    /// + --- + --- + --- + --- +                 + --- + --- + --- + --- +
    /// |  C  |  I  |  Y  |  X  |                 |  13 |  14 |  15 |  16 |
    /// + --- + --- + --- + --- +                 + --- + --- + --- + --- +
    /// </summary>

namespace WordRacer.Domain.Tests.Integration.Fixtures
{
  public class Round1BoardBuilder
  {
    private IGameDictionary _gameDictionary;
    private bool GameDictionaryProvided = false;
    private char _cell1Letter = 'S'; 
    private char _cell2Letter = 'E';
    private char _cell3Letter = 'M';
    private char _cell4Letter = 'H';
    private char _cell5Letter = 'A';
    private char _cell6Letter = 'Q';
    private char _cell7Letter = 'W';
    private char _cell8Letter = 'G';
    private char _cell9Letter = 'B';
    private char _cell10Letter = 'N';
    private char _cell11Letter = 'E';
    private char _cell12Letter = 'O';
    private char _cell13Letter = 'C';
    private char _cell14Letter = 'I';
    private char _cell15Letter = 'Y';
    private char _cell16Letter = 'X';

    private GameCellFactory _gameCellFactory;

    public Round1BoardBuilder()
    {
      _gameCellFactory = new GameCellFactory();
      GameDictionaryProvided = false;
    }

    public Board Build()
    {
      if(!GameDictionaryProvided)
      {
        _gameDictionary = BuildBaseDictionary();
      }

      var gameBoardFactory = new BoardFactory();
      var testBoard = gameBoardFactory.CreateGameBoard(_gameDictionary);

      var cellFactory = new GameCellFactory();

      //row 1 
      var cell1 = cellFactory.CreateGameCell();
      cell1.Character = _cell1Letter.ToString();
      var cell2 = cellFactory.CreateGameCell();
      cell2.Character = _cell2Letter.ToString();
      var cell3 = cellFactory.CreateGameCell();
      cell3.Character = _cell3Letter.ToString();
      var cell4 = cellFactory.CreateGameCell();
      cell4.Character = _cell4Letter.ToString();
      //row 2
      var cell5 = cellFactory.CreateGameCell();
      cell5.Character = _cell5Letter.ToString();
      var cell6 = cellFactory.CreateGameCell();
      cell6.Character = _cell6Letter.ToString();
      var cell7 = cellFactory.CreateGameCell();
      cell7.Character = _cell7Letter.ToString();
      var cell8 = cellFactory.CreateGameCell();
      cell8.Character = _cell8Letter.ToString();
      //row 3
      var cell9 = cellFactory.CreateGameCell();
      cell9.Character = _cell9Letter.ToString();
      var cell10 = cellFactory.CreateGameCell();
      cell10.Character = _cell10Letter.ToString();
      var cell11 = cellFactory.CreateGameCell();
      cell11.Character = _cell11Letter.ToString();
      var cell12 = cellFactory.CreateGameCell();
      cell12.Character = _cell12Letter.ToString();
      //row 4
      var cell13 = cellFactory.CreateGameCell();
      cell13.Character = _cell13Letter.ToString();
      var cell14 = cellFactory.CreateGameCell();
      cell14.Character = _cell14Letter.ToString();
      var cell15 = cellFactory.CreateGameCell();
      cell15.Character = _cell15Letter.ToString();
      var cell16 = cellFactory.CreateGameCell();
      cell16.Character = _cell16Letter.ToString();

      //add cells to board
      testBoard.AddGameCell(cell1);
      testBoard.AddGameCell(cell2);
      testBoard.AddGameCell(cell3);
      testBoard.AddGameCell(cell4);
      testBoard.AddGameCell(cell5);
      testBoard.AddGameCell(cell6);
      testBoard.AddGameCell(cell7);
      testBoard.AddGameCell(cell8);
      testBoard.AddGameCell(cell9);
      testBoard.AddGameCell(cell10);
      testBoard.AddGameCell(cell11);
      testBoard.AddGameCell(cell12);
      testBoard.AddGameCell(cell13);
      testBoard.AddGameCell(cell14);
      testBoard.AddGameCell(cell15);
      testBoard.AddGameCell(cell16);

      //now connect the cells to each other
      //row 1
      testBoard.ConnectTwoCells(cell1, cell2);
      testBoard.ConnectTwoCells(cell1, cell5);
      testBoard.ConnectTwoCells(cell1, cell6);

      testBoard.ConnectTwoCells(cell2, cell3);
      testBoard.ConnectTwoCells(cell2, cell5);
      testBoard.ConnectTwoCells(cell2, cell6);
      testBoard.ConnectTwoCells(cell2, cell7);

      testBoard.ConnectTwoCells(cell3, cell4);
      testBoard.ConnectTwoCells(cell3, cell6);
      testBoard.ConnectTwoCells(cell3, cell7);
      testBoard.ConnectTwoCells(cell3, cell8);

      testBoard.ConnectTwoCells(cell4, cell7);
      testBoard.ConnectTwoCells(cell4, cell8);

      //row 2
      testBoard.ConnectTwoCells(cell5, cell6);
      testBoard.ConnectTwoCells(cell5, cell9);
      testBoard.ConnectTwoCells(cell5, cell10);

      testBoard.ConnectTwoCells(cell6, cell7);
      testBoard.ConnectTwoCells(cell6, cell9);
      testBoard.ConnectTwoCells(cell6, cell10);
      testBoard.ConnectTwoCells(cell6, cell11);

      testBoard.ConnectTwoCells(cell7, cell8);
      testBoard.ConnectTwoCells(cell7, cell10);
      testBoard.ConnectTwoCells(cell7, cell11);
      testBoard.ConnectTwoCells(cell7, cell12);

      testBoard.ConnectTwoCells(cell8, cell11);
      testBoard.ConnectTwoCells(cell8, cell12);

      //row 3
      testBoard.ConnectTwoCells(cell9, cell10);
      testBoard.ConnectTwoCells(cell9, cell13);
      testBoard.ConnectTwoCells(cell9, cell14);

      testBoard.ConnectTwoCells(cell10, cell11);
      testBoard.ConnectTwoCells(cell10, cell13);
      testBoard.ConnectTwoCells(cell10, cell14);
      testBoard.ConnectTwoCells(cell10, cell15);

      testBoard.ConnectTwoCells(cell11, cell12);
      testBoard.ConnectTwoCells(cell11, cell14);
      testBoard.ConnectTwoCells(cell11, cell15);
      testBoard.ConnectTwoCells(cell11, cell16);

      testBoard.ConnectTwoCells(cell12, cell15);
      testBoard.ConnectTwoCells(cell12, cell16);

      //row 4
      testBoard.ConnectTwoCells(cell13, cell14);

      testBoard.ConnectTwoCells(cell14, cell15);

      testBoard.ConnectTwoCells(cell15, cell16);

      return testBoard;
    }

    private GameDictionary BuildBaseDictionary()
    {
      var dictionaryFactory = new DictionaryFactory();
      var baseDictionary = dictionaryFactory.CreateGameDictionary();
      baseDictionary.AddWord("ESS");
      baseDictionary.AddWord("ORT");
      baseDictionary.AddWord("BEE");
      baseDictionary.AddWord("GIT");
      baseDictionary.AddWord("NOG");
      baseDictionary.AddWord("SEAR");
      baseDictionary.AddWord("TREE");
      baseDictionary.AddWord("KIT");
      baseDictionary.AddWord("LOO");
      baseDictionary.AddWord("NOB");
      baseDictionary.AddWord("BOT");
      baseDictionary.AddWord("DREG");
      baseDictionary.AddWord("AMIDS");
      baseDictionary.AddWord("UNARY");
      baseDictionary.AddWord("LOUTED");
      baseDictionary.AddWord("CUSPED");
      baseDictionary.AddWord("CADES");
      baseDictionary.AddWord("CELS");
      baseDictionary.AddWord("NICHED");
      baseDictionary.AddWord("TOPE");
      baseDictionary.AddWord("DUKED");
      baseDictionary.AddWord("CURRED");
      baseDictionary.AddWord("DILLED");
      baseDictionary.AddWord("FOUGHT");
      baseDictionary.AddWord("REDOS");
      baseDictionary.AddWord("ROSED");
      baseDictionary.AddWord("NIBBED");
      baseDictionary.AddWord("DINE");
      baseDictionary.AddWord("TAR");
      baseDictionary.AddWord("FOG");
      baseDictionary.AddWord("TOFU");
      baseDictionary.AddWord("DEN");
      baseDictionary.AddWord("DIN");
      baseDictionary.AddWord("END");
      baseDictionary.AddWord("BIN");
      baseDictionary.AddWord("NIB");
      baseDictionary.AddWord("BEND");
      baseDictionary.AddWord("BIND");
      baseDictionary.AddWord("SEW");
      baseDictionary.AddWord("WEAN");
      return baseDictionary;
    }

    private GameCell BuildGameCell(char letter)
    {
      var gameCell = _gameCellFactory.CreateGameCell();
      gameCell.Character = letter.ToString().ToUpper();
      return gameCell;
    }

    public Round1BoardBuilder WithDictionary(IGameDictionary gameDictionary)
    {
      _gameDictionary = gameDictionary;
      GameDictionaryProvided = true;
      return this;
    }

    public Round1BoardBuilder WithCell1Character(char letter)
    {
      _cell1Letter = letter;
      return this;
    }

    public Round1BoardBuilder WithCell2Character(char letter)
    {
      _cell2Letter = letter;
      return this;
    }

    public Round1BoardBuilder WithCell3Character(char letter)
    {
      _cell3Letter = letter;
      return this;
    }

    public Round1BoardBuilder WithCell4Character(char letter)
    {
      _cell4Letter = letter;
      return this;
    }

    public Round1BoardBuilder WithCell5Character(char letter)
    {
      _cell5Letter = letter;
      return this;
    }

    public Round1BoardBuilder WithCell6Character(char letter)
    {
      _cell6Letter = letter;
      return this;
    }

    public Round1BoardBuilder WithCell7Character(char letter)
    {
      _cell7Letter = letter;
      return this;
    }

    public Round1BoardBuilder WithCell8Character(char letter)
    {
      _cell8Letter = letter;
      return this;
    }

    public Round1BoardBuilder WithCell9Character(char letter)
    {
      _cell9Letter = letter;
      return this;
    }

    public Round1BoardBuilder WithCell10Character(char letter)
    {
      _cell10Letter = letter;
      return this;
    }

    public Round1BoardBuilder WithCell11Character(char letter)
    {
      _cell11Letter = letter;
      return this;
    }

    public Round1BoardBuilder WithCell12Character(char letter)
    {
      _cell12Letter = letter;
      return this;
    }

    public Round1BoardBuilder WithCell13Character(char letter)
    {
      _cell13Letter = letter;
      return this;
    }

    public Round1BoardBuilder WithCell14Character(char letter)
    {
      _cell14Letter = letter;
      return this;
    }

    public Round1BoardBuilder WithCell15Character(char letter)
    {
      _cell15Letter = letter;
      return this;
    }

    public Round1BoardBuilder WithCell16Character(char letter)
    {
      _cell16Letter = letter;
      return this;
    }

  }
}
